from utils.mock_template_util import generate_mock_template, calculate_day
from typing import Dict, List, Any
import random, json, os, ipaddress

"""
相关表建表语句
根据建表语句 解析出表结构关系等信息
"""
EXAMPLE_TASK_TABLE = """
CREATE TABLE `EXAMPLE_TASK_TABLE` (
  `EXAMPLE_ID` varchar(20) NOT NULL COMMENT '样例ID',
  `EXAMPLE_NAME` varchar(200) DEFAULT NULL COMMENT '样例名称',
  `IP_SCOPE` varchar(1000) DEFAULT NULL COMMENT 'IP范围',
  `TASK_RATE` char(1) DEFAULT NULL COMMENT '0-单次立即执行,1-每日,2-每周,3-每月,4-单次定时,5-每小时',
  `TASK_CRON` varchar(20) DEFAULT NULL COMMENT '样例执行时间',
  `CRON_DESC` varchar(100) DEFAULT NULL COMMENT '执行时间说明',
  `TASK_STATUS` char(1) DEFAULT NULL COMMENT '0-草稿,1-待执行,2-执行中,3-终止,4-已完成,5-暂停',
  `TASK_DESC` varchar(1000) DEFAULT NULL COMMENT '样例说明',
  `END_TIME` datetime DEFAULT NULL COMMENT '样例截至时间',
  `CREATE_USER` varchar(20) DEFAULT NULL COMMENT '样例创建人',
  `CREATE_TIME` datetime DEFAULT NULL COMMENT '样例创建时间',
  `SCANNER_TYPE` varchar(100) DEFAULT NULL,
  `SCAN_RESULT_DEAL` varchar(2) DEFAULT NULL COMMENT '扫描结果处理:1交集,2-并集',
  `TASK_TYPE` varchar(2) DEFAULT NULL COMMENT '1-表示,2-表示应用资产扫描，3-存活，4-端口发现（与区分）',
  `TASK_MAIN_ID` varchar(200) DEFAULT NULL COMMENT '子样例,复测样例关联主样例字段',
  `TARGET_NUM` int(11) DEFAULT NULL COMMENT '目标个数',
  `LATEST_EXE_TIME` datetime DEFAULT NULL COMMENT '最近执行时间',
  `NOTIFY_RULE` int(11) DEFAULT NULL COMMENT '最近几次扫描结果均为离线时，发送短信通知。值为0则不发送通知',
  `NOTIFY_USER` varchar(200) DEFAULT NULL COMMENT '通知人用户ID，多个用英文逗号分隔',
  `UPDATE_USER` varchar(20) DEFAULT NULL COMMENT '修改人',
  `UPDATE_TIME` datetime DEFAULT NULL COMMENT '修改时间',
  `PORT_RANGE` varchar(2) DEFAULT NULL COMMENT '端口类型 1-全量端口 2-指定端口',
  PRIMARY KEY (`EXAMPLE_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='样例扫描样例表';
"""

EXAMPLE_TARGET_TABLE = """
CREATE TABLE `EXAMPLE_TARGET_TABLE` (
  `TARGET_ID` varchar(32) NOT NULL COMMENT '主键',
  `EXAMPLE_ID` varchar(20) DEFAULT NULL COMMENT '样例ID',
  `TARGET_IP` varchar(100) DEFAULT NULL COMMENT 'IP',
  `TARGET_PORT` varchar(500) DEFAULT NULL COMMENT '端口',
  `ASSET_ID` varchar(50) DEFAULT NULL COMMENT '资产ID，仅选择资产时存储',
  `ORD` int(11) DEFAULT NULL COMMENT '排序',
  `IP_VAL_START` varchar(50) DEFAULT NULL COMMENT 'IP开始值',
  `IP_VAL_END` varchar(50) DEFAULT NULL COMMENT 'IP结束值',
  `PORT_START` int(11) DEFAULT NULL COMMENT '端口开始值',
  `PORT_END` int(11) DEFAULT NULL COMMENT '端口结束值',
  `PORT_LIST` mediumtext COMMENT '全量端口值',
  PRIMARY KEY (`TARGET_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='样例扫描对象表';
"""

EXAMPLE_TASK_EXE_TABLE = """
CREATE TABLE `EXAMPLE_TASK_EXE_TABLE` (
  `EXE_ID` varchar(20) NOT NULL COMMENT '执行样例ID',
  `EXAMPLE_ID` varchar(20) DEFAULT NULL COMMENT '样例ID',
  `EXE_TIME` decimal(15,0) DEFAULT NULL COMMENT '执行耗时',
  `EXE_STATUS` char(1) DEFAULT NULL COMMENT '执行状态(1 执行中 2 已完成 3 执行失败)',
  `EXE_PERCENT` int(11) DEFAULT NULL COMMENT '执行进度',
  `EXE_DESP` varchar(2000) DEFAULT NULL COMMENT '执行情况说明',
  `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间',
  `UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新时间',
  `TARGET_NUM` int(11) DEFAULT NULL COMMENT '目标个数',
  PRIMARY KEY (`EXE_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='扫描样例执行情况表';
"""

EXAMPLE_ANALYSE_TASK_TABLE = """
CREATE TABLE `EXAMPLE_ANALYSE_TASK_TABLE` (
  `ANALYSIS_ID` varchar(20) NOT NULL COMMENT '主键',
  `EXAMPLE_ID` varchar(20) NOT NULL COMMENT '主样例ID',
  `EXE_ID` varchar(20) NOT NULL COMMENT '执行样例ID',
  `ANALYSE_STATUS` varchar(2) DEFAULT NULL COMMENT '拆解样例状态:3执行失败,2完成,1执行中0待下发',
  `ANALYSE_IP` varchar(2000) DEFAULT NULL,
  `AGENT_URL` varchar(200) DEFAULT NULL COMMENT '采控URL',
  `SCAN_MSG` varchar(1000) DEFAULT NULL COMMENT '下发失败信息或者结果同步失败信息，默认为成功',
  `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间',
  `TARGET_ID` varchar(32) DEFAULT NULL COMMENT '扫描样例与检测对象关系ID',
  PRIMARY KEY (`ANALYSIS_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='样例扫描拆解样例表';
"""

EXAMPLE_SCANNER_REL_TABLE = """
CREATE TABLE `EXAMPLE_SCANNER_REL_TABLE` (
  `SCANNER_NAME` varchar(50) NOT NULL COMMENT '扫描器名称',
  `SCANNER_IP` varchar(100) NOT NULL COMMENT '扫描器IP',
  `SCAN_STATUS` varchar(10) DEFAULT NULL COMMENT '扫描状态：3失败,2成功,1执行中,0待执行',
  `SCAN_TIME` datetime DEFAULT NULL COMMENT '扫描时间',
  `ANALYSE_EXAMPLE_ID` varchar(50) NOT NULL COMMENT '拆解样例ID',
  `EXE_ID` varchar(50) NOT NULL COMMENT '执行样例ID',
  `EXAMPLE_ID` varchar(50) NOT NULL COMMENT '主样例ID',
  `CREATE_TIME` datetime DEFAULT NULL COMMENT '创建时间',
  `SCAN_MSG` varchar(100) DEFAULT NULL COMMENT '扫描成功/失败原因',
  `SCAN_REL_ID` varchar(50) NOT NULL COMMENT '主键',
  PRIMARY KEY (`SCAN_REL_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='样例拆解样例与扫描器关系表';
"""

EXAMPLE_SURVIVE_EXE_RESULT_TABLE = """
CREATE TABLE `EXAMPLE_SURVIVE_EXE_RESULT_TABLE` (
  `RESULT_ID` varchar(50) NOT NULL COMMENT '主键',
  `EXE_ID` varchar(50) DEFAULT NULL COMMENT '执行样例ID',
  `ANALYSIS_ID` varchar(50) DEFAULT NULL COMMENT '拆解样例ID',
  `ASSET_ID` varchar(50) DEFAULT NULL COMMENT '资产ID，手输的IP+主机类型匹配资产',
  `IP` varchar(100) DEFAULT NULL COMMENT '单个IP',
  `PORT` varchar(50) DEFAULT NULL COMMENT '端口',
  `IP_STATUS` varchar(2) DEFAULT NULL COMMENT 'IP状态：0-离线，1-在线',
  `PORT_STATUS` varchar(2) DEFAULT NULL COMMENT '端口状态：0-离线，1-在线',
  `FIND_TIME` datetime DEFAULT NULL COMMENT '发现时间',
  `PORT_RULE_TYPE` varchar(2) DEFAULT NULL COMMENT '端口类型 0-高危 1-合法 2-非法 3-未知',
  `SERVER` varchar(100) DEFAULT NULL COMMENT '服务',
  `PRODUCT` varchar(200) DEFAULT NULL COMMENT '端口所属组件',
  `PRODUCT_VER` varchar(60) DEFAULT NULL COMMENT '端口所属组件版本号',
  PRIMARY KEY (`RESULT_ID`),
  KEY `idx_exe_id` (`EXE_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='存活结果表';
"""

# 组合表列表 需要生成的表 请放入此列表
TABLES = [
    EXAMPLE_TASK_TABLE,
    EXAMPLE_TARGET_TABLE,
    EXAMPLE_TASK_EXE_TABLE,
    EXAMPLE_ANALYSE_TASK_TABLE,
    EXAMPLE_SCANNER_REL_TABLE,
    EXAMPLE_SURVIVE_EXE_RESULT_TABLE,
]

# 表关系 配置表之间的关联关系 用于生成有依赖关系的数据
RELATIONS = [
    ["EXAMPLE_TASK_TABLE.EXAMPLE_ID", "EXAMPLE_TARGET_TABLE.EXAMPLE_ID"],
    ["EXAMPLE_TASK_TABLE.EXAMPLE_ID", "EXAMPLE_TASK_EXE_TABLE.EXAMPLE_ID"],
    ["EXAMPLE_TASK_EXE_TABLE.EXAMPLE_ID", "EXAMPLE_ANALYSE_TASK_TABLE.EXAMPLE_ID"],
    ["EXAMPLE_TASK_EXE_TABLE.EXE_ID", "EXAMPLE_ANALYSE_TASK_TABLE.EXE_ID"],
    ["EXAMPLE_TARGET_TABLE.TARGET_ID", "EXAMPLE_ANALYSE_TASK_TABLE.TARGET_ID"],
    ["EXAMPLE_TARGET_TABLE.TARGET_IP", "EXAMPLE_ANALYSE_TASK_TABLE.ANALYSE_IP"],
    ["EXAMPLE_ANALYSE_TASK_TABLE.EXAMPLE_ID", "EXAMPLE_SCANNER_REL_TABLE.EXAMPLE_ID"],
    ["EXAMPLE_ANALYSE_TASK_TABLE.EXE_ID", "EXAMPLE_SCANNER_REL_TABLE.EXE_ID"],
    [
        "EXAMPLE_ANALYSE_TASK_TABLE.ANALYSIS_ID",
        "EXAMPLE_SCANNER_REL_TABLE.ANALYSE_EXAMPLE_ID",
    ],
    ["EXAMPLE_ANALYSE_TASK_TABLE.EXE_ID", "EXAMPLE_SURVIVE_EXE_RESULT_TABLE.EXE_ID"],
    [
        "EXAMPLE_ANALYSE_TASK_TABLE.ANALYSIS_ID",
        "EXAMPLE_SURVIVE_EXE_RESULT_TABLE.ANALYSIS_ID",
    ],
    [
        "EXAMPLE_ANALYSE_TASK_TABLE.ANALYSE_IP",
        "EXAMPLE_SURVIVE_EXE_RESULT_TABLE.IP",
    ],
]

# 字段规则 定义各表字段的生成规则
# 具体的语法见 rule.py 中的说明
FIELD_RULE = {
    "EXAMPLE_TASK_TABLE": {
        "EXAMPLE_ID": "str@MOCKuid\\(16\\)",
        "EXAMPLE_NAME": "str@存活性-\\d{4}",
        "CREATE_TIME": "apply@date@+120",
        "LATEST_EXE_TIME": "apply@date@+1900",
        "UPDATE_TIME": "apply@date@+1900",
    },
    "EXAMPLE_TARGET_TABLE": {
        "TARGET_ID": "str@MOCKuid\\(16\\)",
        "ASSET_ID": "extra@EXTRA_ASSET.json@ASSET_ID@each",
        "TARGET_PORT": "extra@PORT_DATA.json@PORT@join@,",
        "PORT_LIST": "extra@PORT_DATA.json@PORT@join@,",
        "TARGET_IP": "extra@EXTRA_ASSET.json@IP@select[ASSET_ID]",
        "ORD": "str@\\d{1,2}",
    },
    "EXAMPLE_TASK_EXE_TABLE": {
        "EXE_ID": "str@EXEMuid\\(16\\)",
        "CREATE_TIME": "apply@date@+1700",
        "UPDATE_TIME": "apply@date@+1820",
        "TARGET_NUM": "extra@EXTRA_ASSET.json@ASSET_ID@length",
    },
    "EXAMPLE_ANALYSE_TASK_TABLE": {
        "ANALYSIS_ID": "str@MOCKuid\\(16\\)",
        "CREATE_TIME": "apply@date@+1820",
    },
    "EXAMPLE_SCANNER_REL_TABLE": {
        "SCAN_REL_ID": "str@MOCKuid\\(16\\)",
        "SCAN_TIME": "apply@date@+1830",
        "CREATE_TIME": "apply@date@+1830",
    },
    "EXAMPLE_SURVIVE_EXE_RESULT_TABLE": {
        "RESULT_ID": "str@MOCKuid\\(16\\)",
        "ASSET_ID": "extra@EXTRA_ASSET.json@ASSET_ID@select[IP]",
        "PORT": "extra@PORT_DATA.json@PORT@each",
        "PORT_STATUS": "str@[01]{1}",
        "FIND_TIME": "apply@date@+1840",
    },
    "tl_log_user": {
        "USER_LOG_ID": "str@MOCKuid\\(16\\)",
        "USER_ACCOUNT_ID": "0",
        "USER_ACCOUNT_NAME": "admin",
        "USER_NAME": "admin",
        "SESSION_ID": "str@[0-9A-F]{32}",
        "USER_IP": "str@10\\.44\\.105\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",
        "USER_PORT": "str@[0-9]{1,5}",
    },
}

# 模板数据 定义各表的模板数据 用于生成初始数据
TEMPLATES = {
    "EXAMPLE_TASK_TABLE": [
        {
            "EXAMPLE_ID": "TASK5053404065972054",
            "EXAMPLE_NAME": "测试数据",
            "IP_SCOPE": None,
            "TASK_RATE": "0",
            "TASK_CRON": "IMMEDIATE",
            "CRON_DESC": "立即执行",
            "TASK_STATUS": "4",
            "TASK_DESC": "",
            "END_TIME": None,
            "CREATE_USER": "0",
            "CREATE_TIME": "24/10/2024 17:56:34",
            "SCANNER_TYPE": "4",
            "SCAN_RESULT_DEAL": "1",
            "TASK_TYPE": "3",
            "TASK_MAIN_ID": None,
            "TARGET_NUM": 5,
            "LATEST_EXE_TIME": "24/10/2024 18:05:01",
            "NOTIFY_RULE": 0,
            "NOTIFY_USER": None,
            "UPDATE_USER": "0",
            "UPDATE_TIME": "24/10/2024 18:00:05",
            "PORT_RANGE": None,
        }
    ],
    "EXAMPLE_TARGET_TABLE": [
        {
            "TARGET_ID": "TARG1344353233044608",
            "EXAMPLE_ID": "TASK5053404065972054",
            "TARGET_IP": "192.168.111.174",
            "TARGET_PORT": "22,3320,8888,9999",
            "ASSET_ID": "ASSE2747210517695420",
            "ORD": 3,
            "IP_VAL_START": None,
            "IP_VAL_END": None,
            "PORT_START": None,
            "PORT_END": None,
            "PORT_LIST": "22,3320,8888,9999",
        }
    ],
    "EXAMPLE_TASK_EXE_TABLE": [
        {
            "EXE_ID": "EXE03252827110372607",
            "EXAMPLE_ID": "TASK5053404065972054",
            "EXE_TIME": 1.0,
            "EXE_STATUS": "2",
            "EXE_PERCENT": 100,
            "EXE_DESP": "执行成功",
            "CREATE_TIME": "24/10/2024 18:03:01",
            "UPDATE_TIME": "24/10/2024 18:05:01",
            "TARGET_NUM": 5,
        }
    ],
    "EXAMPLE_ANALYSE_TASK_TABLE": [
        {
            "ANALYSIS_ID": "ANAL1965158330973578",
            "EXAMPLE_ID": "TASK5053404065972054",
            "EXE_ID": "EXE03252827110372607",
            "ANALYSE_STATUS": "2",
            "ANALYSE_IP": "10.21.171.130",
            "AGENT_URL": "http://xxx.xxx.xxx.xxx:8300/agent",
            "SCAN_MSG": "执行成功",
            "CREATE_TIME": "24/10/2024 18:03:01",
            "TARGET_ID": "TARG2607661385886247",
        },
    ],
    "EXAMPLE_SCANNER_REL_TABLE": [
        {
            "SCANNER_NAME": "rustNmap",
            "SCANNER_IP": "xxx.xxx.xxx.xxx",
            "SCAN_STATUS": "2",
            "SCAN_TIME": "24/10/2024 18:04:00",
            "ANALYSE_EXAMPLE_ID": "ANAL1965158330973578",
            "EXE_ID": "EXE03252827110372607",
            "EXAMPLE_ID": "TASK5053404065972054",
            "CREATE_TIME": "24/10/2024 18:03:01",
            "SCAN_MSG": "执行成功",
            "SCAN_REL_ID": "ANSC0950582844056157",
        }
    ],
    "EXAMPLE_SURVIVE_EXE_RESULT_TABLE": [
        {
            "RESULT_ID": "RES03185508605221361",
            "EXE_ID": "EXE03252827110372607",
            "ANALYSIS_ID": "ANAL9034643553977267",
            "ASSET_ID": "ASSE2747210517695420",
            "IP": "192.168.111.174",
            "PORT": "22",
            "IP_STATUS": "0",
            "PORT_STATUS": "0",
            "FIND_TIME": "24/10/2024 18:05:01",
            "PORT_RULE_TYPE": "3",
            "SERVER": None,
            "PRODUCT": None,
            "PRODUCT_VER": None,
        },
    ],
    "tl_log_user": [
        {
            "LOG_DESC": "新增样例数据成功",
            "LOG_LEVEL": 1,
            "LOG_LEVEL_DESC": "低",
            "LOG_CATAGORY": 3,
            "LOG_CATAGORY_DESC": "业务操作管理",
            "LOG_SUB_CATAGORY": 7,
            "LOG_SUB_CATAGORY_DESC": "OPERATION_ASSET",
            "OP_RESULT": 1,
            "MOD_CODE": "ASSET",
            "OP_CODE": "P_ASSET_PORT_DETECT_TASK_OPT_SUC",
            "module_name": "样例模块",
        },
        {
            "LOG_DESC": "查看样例详情",
            "LOG_LEVEL": 0,
            "LOG_LEVEL_DESC": "正常",
            "LOG_CATAGORY": 3,
            "LOG_CATAGORY_DESC": "业务操作管理",
            "LOG_SUB_CATAGORY": 7,
            "LOG_SUB_CATAGORY_DESC": "OPERATION_ASSET",
            "OP_RESULT": 1,
            "MOD_CODE": "ASSET",
            "OP_CODE": "P_ASSET_PORT_DETECT_TASK_DETAIL",
            "module_name": "样例模块",
        },
        {
            "LOG_DESC": "查询样例执行详情",
            "LOG_LEVEL": 0,
            "LOG_LEVEL_DESC": "正常",
            "LOG_CATAGORY": 3,
            "LOG_CATAGORY_DESC": "业务操作管理",
            "LOG_SUB_CATAGORY": 7,
            "LOG_SUB_CATAGORY_DESC": "OPERATION_ASSET",
            "OP_RESULT": 1,
            "MOD_CODE": "ASSET",
            "OP_CODE": "P_ASSET_PORT_SCAN_TASK_QUERY_EXE_SUCC",
            "module_name": "样例模块",
        },
    ],
}

# 文件需要事先准备好 也可以在该模块中生成好存储到 asset 目录下
EXTRA_DATA = ["asset/EXTRA_ASSET.json", "asset/PORT_DATA.json"]
# "even"（均分填充）将数据尽可能平均分到每天（如 5 条分给 3 天 →[2,2,1]），不足不补
# "cycle"（循环迭代）数据不够时循环使用，确保每天至少有1 条（如 2 条分 5 天 →[A,B,A,B,A]）
# "full"（全部复制）每天使用全部数据（如 2 条 → 每天都是[A,B]）
DISTRIBUTION_STRATEGY = "cycle" 
# 时间范围 如果不输入则只生成当日数据
TIME_RANGE = ["2025-10-01", "2025-10-31"]
# 均分每日时间段数量
DAY_NUM = 2
# 模块名称
MODULE_NAME = "example"

# 生成端口数据相关配置 属于额外自定义配置
PORT_DAY_NUM = 5

# 生成端口数据文件 自定义函数
def generate_extra_port_data():
    # Step 1: 计算基准长度
    base_len = len(calculate_day(TIME_RANGE, DAY_NUM))
    port_len = base_len * PORT_DAY_NUM

    # Step 2: 生成比 port_len 多几个的端口（比如多 10 个，或至少 +1）
    extra_count = max(1, int(port_len * 0.1))  # 至少多1个，或按比例加
    total_needed = port_len + extra_count

    # Step 3: 定义可用端口范围（避开知名端口 <1024）
    min_port = 1024
    max_port = 65535
    available_ports = list(range(min_port, max_port + 1))

    if total_needed > len(available_ports):
        raise ValueError(
            f"需要 {total_needed} 个端口，但可用端口仅 {len(available_ports)} 个！"
        )

    # Step 4: 随机采样（避免重复）
    selected_ports = random.sample(available_ports, total_needed)

    # Step 5: 转为所需格式 [{"PORT": "6379"}, ...]
    port_list = [{"PORT": str(p)} for p in selected_ports]

    # Step 6: 写入 JSON 文件
    os.makedirs("asset", exist_ok=True)
    with open("asset/PORT_DATA.json", "w", encoding="utf-8") as f:
        json.dump(port_list, f, ensure_ascii=False, indent=2)

# 生成资产数据文件 自定义函数
def generate_extra_asset_data():
    # 生成约莫200条资产数据 [{"ASSET_ID": "ASSExxxx", "IP": "192.168.x.x"}, ...]
    # 写入 asset/EXTRA_ASSET.json
    num_assets = 200
    assets = []

    # 预定义一些常见的子网段，模拟真实环境分布
    subnets = [
        "192.168.1.0/24",
        "192.168.10.0/24",
        "192.168.20.0/24",
        "10.0.1.0/24",
        "10.0.2.0/24",
        "172.16.0.0/24",
        "172.16.1.0/24",
    ]

    used_ips = set()  # 避免IP重复

    for i in range(1, num_assets + 1):
        asset_id = f"ASSE{i:04d}"  # ASSE0001, ASSE0002, ..., ASSE0200

        # 尝试生成不重复的IP（最多重试10次）
        ip = None
        for _ in range(10):
            subnet = random.choice(subnets)
            network = ipaddress.IPv4Network(subnet, strict=False)
            # 排除网络地址和广播地址
            ip_int = random.randint(
                int(network.network_address) + 1, int(network.broadcast_address) - 1
            )
            candidate_ip = str(ipaddress.IPv4Address(ip_int))
            if candidate_ip not in used_ips:
                ip = candidate_ip
                used_ips.add(ip)
                break

        # 若未能生成唯一IP，则用简单递增方式兜底（极端情况）
        if ip is None:
            base_ip = "192.168.1."
            ip = f"{base_ip}{(i % 254) + 1}"
            while ip in used_ips:
                i += 1
                ip = f"{base_ip}{(i % 254) + 1}"
            used_ips.add(ip)

        assets.append({"ASSET_ID": asset_id, "IP": ip})

    # 写入文件
    os.makedirs("asset", exist_ok=True)
    with open("asset/EXTRA_ASSET.json", "w", encoding="utf-8") as f:
        json.dump(assets, f, indent=2, ensure_ascii=False)

# 生成配置文件函数 统一接口
def generate_config(
    templates: Dict[str, Any] = TEMPLATES,
    extra_datas: List = EXTRA_DATA,
    distribution_strategy: str = DISTRIBUTION_STRATEGY,
    time_range: List = TIME_RANGE,
    day_num: int = DAY_NUM,
):
    # 生成资产JSON文件
    generate_extra_asset_data()
    # 生成端口号JSON文件
    generate_extra_port_data()

    return generate_mock_template(
        MODULE_NAME,
        TABLES,
        RELATIONS,
        FIELD_RULE,
        templates,
        extra_datas,
        distribution_strategy,
        time_range,
        day_num,
    )

# 暴露函数
__all__ = ["generate_config"]
